package net.peelmeagrape.hibernate.collections;

import net.peelmeagrape.hibernate.xmlgen.AddPropertyNameAsAttribute;
import net.peelmeagrape.hibernate.xmlgen.XmlAttribute;
import net.peelmeagrape.hibernate.xmlgen.XmlElement;
import net.peelmeagrape.hibernate.xmlgen.ChildElement;
import net.peelmeagrape.hibernate.*;
import net.peelmeagrape.hibernate.sql.*;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;

/**
 * Lets you map a List (or Collection) with bag semantics.
 */
@Target({METHOD, FIELD}) @Retention(RUNTIME)
@XmlElement(name="idbag")
@AddPropertyNameAsAttribute(name="name")
public @interface H8IdBag
{
    /**
     * The strategy Hibernate should use for accessing the property value. This may be one of
     * 'property', 'field', 'embedded', or the name of a subclass of {@link org.hibernate.property.PropertyAccessor}.
     */
    @XmlAttribute String access() default "property";

    /**
     * (optional - defaults to property name) the name of the collection table (not used for one-to-many associations).
     */
    @XmlAttribute String table() default "";

    /**
     * the name of a table schema to override the schema declared on the root element.
     */
    @XmlAttribute String schema() default "";
    /**
     * the name of a table catalog to override the schema declared on the root element.
     */
    @XmlAttribute String catalog() default "";
    @XmlAttribute String subselect() default "";

    /**
     * enable lazy initialization.
     */
    @XmlAttribute boolean lazy() default true;

    /**
     * enable operations to cascade to child entities. (from glancing through hibernate code, only
     * 'delete-orphan' seems to have any effect?)
     */
    @XmlAttribute String cascade() default "";

    /**
     * (optional, JDK1.4 only) specify a table column (or columns) that define the iteration order of the Map, Set  or bag, together with an optional asc or desc.
     */
    @XmlAttribute("order-by") String orderBy() default "";

    /**
     * specify an arbitrary SQL WHERE  condition to be used when retrieving or removing the collection
     * (useful if the collection should contain only a subset of the available data)
     */
    @XmlAttribute String where() default "";

    /**
     * specify a "batch size" for lazily fetching instances of this collection.
     */
    @XmlAttribute("batch-size") int batchSize() default 1;
    @XmlAttribute OuterJoinSetting outerJoin() default OuterJoinSetting.AUTO;

    /**
     * Choose between outer-join fetching, fetching by sequential select, and fetching by sequential subselect.
     * Only one collection may be fetched by outer join per SQL SELECT.
     */
    @XmlAttribute FetchSetting fetch() default FetchSetting.SELECT;

    @XmlAttribute String persister() default "";
    @XmlAttribute("collection-type") String collectionType() default "";
    @XmlAttribute String check() default "";

    /**
     * Species that changes to the state of the collection results in increment of the owning entity's version.
     * (For one to many associations, it is often reasonable to disable this setting.)
     */
    @XmlAttribute("optimistic-lock") boolean optimisticLock() default true;
    @XmlAttribute String node() default "";
    @XmlAttribute("embed-xml") boolean embedXml() default true;

    @ChildElement(0) Meta[] meta() default {};
    @ChildElement(2) Cache[] cache() default {};
    @ChildElement(3) Synchronize[] synchronize() default {};
    @ChildElement(4) Comment[] comment() default {};
    @ChildElement(5) CollectionId id();
    @ChildElement(6) Key key();
    @ChildElement(7) CollectionValue value() default @CollectionValue(otm= @OneToMany);
    @ChildElement(8) Filter[] filters() default {};

    @ChildElement(9) Loader[] loader() default {};
    @ChildElement(10) SqlInsert[] sqlInsert() default {};
    @ChildElement(11) SqlUpdate[] sqlUpdate() default {};
    @ChildElement(12) SqlDelete[] sqlDelete() default {};
    @ChildElement(13) SqlDeleteAll[] sqlDeleteAll() default {};
}
